package com.example.blog.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.blog.mapper.AdminMapper;
import com.example.blog.mapper.UserMapper;
import com.example.blog.pojo.*;
import com.example.blog.service.UserService;
import com.example.blog.util.TokenUtil.JwtUtils;
import com.example.blog.util.TokenUtil.decryptToken;
import com.example.blog.util.TokenUtil.spiltUtils;
import com.example.blog.util.UserUtils.OnlineUserStatsService;
import com.example.blog.util.UserUtils.UserUtils;
import com.xiaoleilu.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.List;

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private AdminMapper adminMapper;
    @Resource
    private UserUtils userIdUtil;
    @Resource
    private OnlineUserStatsService onlineUserStatsService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /***
     * 登录逻辑
     * @param loginRequest 用户名密码
     * @return 返回登录结果
     */
    @Override
    @Transactional
    public Result<T> login(LoginRequest loginRequest, HttpServletResponse response) {
        //判断用户名密码是否为空
        if (StringUtils.isEmpty(loginRequest.getUsername()) || StringUtils.isEmpty(loginRequest.getPassword())) {
            return Result.ACCOUNT();
        }

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", loginRequest.getUsername());

        //查询是否有此用户
        User login = userMapper.selectOne(queryWrapper);
        if (login == null) {
            return Result.failed();
        }
        //判断密码是否正确
        if (!login.getPassword().equals(loginRequest.getPassword())) {
            return Result.failed();
        }
        String token = JwtUtils.createToken(loginRequest.getPassword() + ":" + loginRequest.getUsername());
        // 将 token 存入 Cookie 中
        if (token != null) {
            Cookie cookie = new Cookie("token", token);
            cookie.setPath("/");
            cookie.setHttpOnly(true);
            cookie.setMaxAge(60 * 60 * 24 * 7);
            response.addCookie(cookie);
            onlineUserStatsService.online(login.getId());
            return Result.success("登录成功！");
        }
        return Result.failed("登陆失败！");
    }

    @Override
    public Result<String> QRCodeLogin(Integer userId, HttpServletResponse response) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        QueryWrapper<User> wrapper = queryWrapper.eq("id", userId);
        User user = userMapper.selectOne(wrapper);
        if (user != null) {
            String token = JwtUtils.createToken(user.getPassword() + ":" + user.getUsername());
            if (token != null) {
                Cookie cookie = new Cookie("token", token);
                cookie.setPath("/");
                cookie.setHttpOnly(true);
                cookie.setMaxAge(60 * 60 * 24 * 7 * 7);
                response.addCookie(cookie);
                onlineUserStatsService.online(userId);
                return Result.success("登录成功！");
            }
            return Result.failed("登陆失败！");
        } else {
            return Result.failed("无此用户");
        }
    }

    /***
     * 退出登录逻辑
     * @param token
     * @return
     */
    @Override
    public Result<T> outLogin(String token, HttpServletResponse response) {
        String pe = decryptToken.decrypt(token);
        if (pe != null) {
            String userName = spiltUtils.getUserName(pe);
            Integer userId = userIdUtil.getUserId(userName);
            Cookie cookie = new Cookie("token", null);
            cookie.setPath("/");
            cookie.setHttpOnly(true);
            cookie.setMaxAge(0);
            response.addCookie(cookie);
            onlineUserStatsService.outOnline(userId);
            return Result.success("退出登录成功！");
        }
        return Result.failed("您还没有登录！");
    }

    /***
     * 根据保存到redis里的token查询登录用户数量
     */
    @Override
    public Result<T> tokenCount() {
        Long count = this.onlineUserStatsService.count();
        return Result.success("当前在线人数为：" + count);
    }


    /***
     * 注册逻辑
     * @return 注册结果
     */
    @Override
    public Result<T> register(User user) {
        // 校验用户名或者密码是否为空
        String username = user.getUsername();
        String password = user.getPassword();
        String sex = user.getSex();
        int age = user.getAge();
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
            return Result.ACCOUNT();
        }
        if (StringUtils.isBlank(sex) || "".equals(String.valueOf(age))) {
            return Result.ACCOUNT("性别和年龄不能为空！");
        }

        //密码和用户名必须是数字和字母组成且不超过10位
        if (!username.matches("^[a-zA-Z0-9]{1,10}$") || !password.matches("^[a-zA-Z0-9]{1,10}$")) {
            return Result.unauthorized();
        }

        //查询是否存在同名的用户
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", user.getUsername()).eq("password", user.getPassword());
        User existUser = userMapper.selectOne(queryWrapper);

        if (existUser != null) {
            return Result.PARAMS();
        }
        //判断输入年龄是否合理
        if (age > 100) {
            return Result.failed("请输入合法年龄！");
        }
        int insertResult = userMapper.insert(user);
        if (insertResult <= 0) {
            return Result.unauthorized();
        }
        return Result.success("注册成功！");
    }

    /***
     * 根据用户id查询用户信息
     * @param id
     * @return
     */
    @Override
    public Result<User> getUserById(int id) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("id", id);
        List<User> list = userMapper.selectList(wrapper);
        String json = JSONUtil.toJsonStr(list);
        User user = JSONObject.parseObject(json, User.class);
        return Result.success(user);
    }


    // 根据用户名获取用户
    @Override
    public User getByUserName(String username) {
        return lambdaQuery().eq(User::getUsername, username).one();
    }

    /***
     * 修改用户信息
     * @param user
     * @return 修改结果
     */
    @Override
    public Result<T> updateUserRecord(User user, String token) {
        String ps = decryptToken.decrypt(token);
        String password = spiltUtils.getPassWord(ps);
        //通过密码查询管理员信息
        QueryWrapper<Admin> wrapper = new QueryWrapper<>();
        wrapper.eq("password", password);
        List<Admin> list = adminMapper.selectList(wrapper);
        //如果管理员存在
        if (list.size() > 0) {
            //进行修改或删除
            int update = userMapper.updateById(user);
            if (update > 0) {
                return Result.success("修改成功！");
            }
            return Result.failed("修改失败！");
        }
        return Result.failed("没有权限");
    }

    /***
     * 删除用户信息
     * @param id
     * @return 删除结果
     */
    @Override
    public Result<T> deleteUserRecord(int id, String token) {
        //解析获取的token数据
        String ps = decryptToken.decrypt(token);
        String password = spiltUtils.getPassWord(ps);
        //通过密码查询管理员信息
        QueryWrapper<Admin> wrapper = new QueryWrapper<>();
        wrapper.eq("password", password);
        List<Admin> list = adminMapper.selectList(wrapper);
        //如果管理员存在
        if (list.size() > 0) {
            User user = userMapper.selectById(id);
            if (user == null) {
                return Result.failed("此用户不存在！");
            }
            String HeaderImgPath = user.getHeaderurl();
            String imageName = HeaderImgPath.substring(HeaderImgPath.lastIndexOf("/") + 1);
            int delete = userMapper.deleteById(id);
            if (delete > 0) {
                File file = new File("header/" + imageName);
                if (file.exists()) {
                    file.delete();
                    return Result.success("删除成功！");
                }
            }

            return Result.failed("删除失败！");
        }
        return Result.failed("没有权限！");
    }

    /***
     * 展示当前登录用户信息
     * @param token 获取当前登录用户的token
     * @return token中获取的用户名对应的用户信息
     */
    @Override
    public Result<UserInfo> queryCurrentUserInfo(String token) {
        String pe = decryptToken.decrypt(token);
        String userName = spiltUtils.getUserName(pe);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", userName).select("nickname", "headerurl", "id");
        UserInfo userInfo = userMapper.getUserInfo(userName);
        return Result.success(userInfo);
    }

    /***
     * 获取全部已注册用户
     * @return
     */
    @Override
    public List<User> getAllUsers() {
        return userMapper.selectList(null);
    }
}

